package io.github.uicdb.et.register;

import io.github.uicdb.et.element.BasicElement;
import io.github.uicdb.et.fluid.ElementStream;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageType;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.fluids.FluidType;
import net.neoforged.neoforge.registries.DeferredHolder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;

@RequiredArgsConstructor

public class ElementalObject {
    @Getter
    final ResourceLocation key;
    final Holder<BasicElement> element;
    //元素伤害加成
    @Getter
    final Holder<Attribute> increasing;
    @Getter
    final Holder<Potion> potionIncreasing;
    final ResourceKey<DamageType> damageType;
    @Getter
    final DeferredHolder<FluidType,FluidType> fluidType;
    @Getter
    final DeferredHolder<Fluid, ElementStream.Source> fluidSource;
    @Getter
    final DeferredHolder<Fluid,ElementStream.Flowing> fluidFlowing;
    public BasicElement getElement() {
        return element.value();
    }

    public DamageSource getDamageSource(Level level, @Nullable Entity entity) {
        var type = getDamageType(level);
        return new DamageSource(type, entity);
    }

    public boolean hasDamageType(Level level) {
        return level.damageSources().damageTypes.getHolder(damageType).isPresent();
    }
    public Holder<DamageType> getDamageType(Level level) {
        return level.damageSources().damageTypes.getHolder(damageType).orElseGet(() -> level.damageSources().damageTypes.getHolderOrThrow(DamageTypes.GENERIC));
    }

    public DamageSource getDamageSourceInDirect(@NotNull Entity direct, Entity inDirect) {
        var type = getDamageType(direct.level());
        return new DamageSource(type, direct, inDirect);
    }

    public DamageSource getDamageSourceAt(Level level, Vec3 pos) {
        var type = getDamageType(level);
        return new DamageSource(type, pos);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof ElementalObject that)) return false;
        return Objects.equals(key, that.key);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(key);
    }

    public Holder<BasicElement> getElementHolder() {
        return element;
    }

    ResourceLocation icon =null;
    public ResourceLocation getIcon() {
        if(icon == null) icon = ResourceLocation.fromNamespaceAndPath(key.getNamespace(),"textures/element/"+key.getPath()+".png");
        return icon;
    }
}
